#!/bin/bash
# 获取ESTABLISHED连接数最多的前10个ip并写入临时文件/tmp/DDoS/temp_dropip,排除了内部ip段192.168|127.0开头的.通过for循环将temp_dropip里面的ip通过iptables全部drop掉，然后写到日志文件/var/log/ddos
# ESTABLISHED的意思是建立连接。表示两台机器正在通信
# chmod +x /root/bin/DDoS.sh
# 计时器*/1 * * * * /root/bin/DDoS.sh
ESTABLISHED_NUM=4 #一分钟内的还在连接的次数
TIME_LENGTH=5     #当前时间以前多少分钟
CURRENT=$(date "+%Y-%m-%d %H:%M:%S")
TIMESTAMP=$(date -d "$CURRENT" +%s)
t2=$(($TIMESTAMP + $TIME_LENGTH * 60))
DIR="/tmp/DDoS/"
if [ ! -d $DIR ]; then
    mkdir -p $DIR
fi
SOURCE="${DIR}dropip.txt"
TEMP_SOURCE="${DIR}temp_dropip.txt"
DEL_TARGET="${DIR}target.txt"
TMP="${DIR}temp.txt"

#校验ip是否合法
function check_ip() {
    IP=$1
    if [[ $IP =~ ^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$ ]]; then
        FIELD1=$(echo $IP | cut -d. -f1)
        FIELD2=$(echo $IP | cut -d. -f2)
        FIELD3=$(echo $IP | cut -d. -f3)
        FIELD4=$(echo $IP | cut -d. -f4)
        if [ $FIELD1 -le 255 -a $FIELD2 -le 255 -a $FIELD3 -le 255 -a $FIELD4 -le 255 ]; then
            return 1
        else
            return 0
        fi
    else
        return 0
    fi
}

#删除重复的黑名单
iptables -vnL | grep DROP | awk '{ print $8}' | grep -v "0.0.0.0" | awk '/[0-9]/' | sort | uniq -c | sort -nr | awk '{if($1 >1) print $1" "$2}' | awk '{for(i=1;i<=$1-1;i++) print "iptables -D INPUT -s  "$2" -j DROP" | "bash" }'
/bin/netstat -na | grep ESTABLISHED | awk '{print $5}' | awk -F: '{print $1}' | sort | uniq -c | sort -rn | head -10 | grep -v -E '192.168|127.0' | awk '{if ($2!=null && $1>established_num) {print $2}}' established_num="$ESTABLISHED_NUM" >${TEMP_SOURCE}
if [ -s $TEMP_SOURCE ]; then
    for i in $(cat "${TEMP_SOURCE}"); do
        check_ip "$i"
        if [ $? -eq 1 ]; then
            if [ $(iptables -vnL | grep -c "$i") -eq 0 ]; then
                /sbin/iptables -A INPUT -s $i -j DROP
                echo "$i kill at $(date)" >>/var/log/ddos
            fi
        fi
    done
fi

cat ${TEMP_SOURCE} | awk '{if($0!=null){print nowTime"@"$0 > sourceV}}' nowTime="$TIMESTAMP" sourceV="$SOURCE"
if [ -s $SOURCE ]; then
    cat ${SOURCE} | awk -F "@" '{if($1<t2Time){print $2>del_target}else{print $1"@"$2 > temp_target}}' t2Time="$t2" del_target="$DEL_TARGET" temp_target="$TMP"
    if [ $? -eq 0 ]; then
        for i in $(cat "${DEL_TARGET}"); do
            check_ip "$i"
            if [ $? -eq 1 ]; then
                #存在黑名单ip就移除掉
                if [ $(iptables -vnL | grep -c "$i") -ne 0 ]; then
                    iptables -D INPUT -s "$i" -j DROP
                fi
            fi
        done
        cp $TMP $SOURCE
        rm -rf $DEL_TARGET
        rm -rf $TMP
    fi
fi
